bitkeeper revision 1.771 (4049ededjtcDNSaY2uNyUCnZr9OuKw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 6 Mar 2004 15:27:41 +0000 (15:27 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 6 Mar 2004 15:27:41 +0000 (15:27 +0000)
console.c, sched.h:
  DOM0 now has bidirectional serial console.

xen/drivers/char/console.c
xen/include/xeno/sched.h
xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c

index 6728a32896184a728d69b95c835cbb518c306b3d..370c4494234553cc2460942806a4ffc86b00e18f 100644 (file)
@@ -241,6 +241,7 @@ static void serial_rx(unsigned char c, struct pt_regs *regs)
     if ( c == CTRL_A )
     {
         xen_rx = !xen_rx;
+        serial_putc(sercon_handle, '\n');
         printk("*** Serial input -> %s "
                "(type 'CTRL-a' to switch input to %s).\n",
                input_str[xen_rx], input_str[!xen_rx]);
@@ -422,6 +423,13 @@ long do_console_write(char *str, unsigned int count)
 
     return 0;
 #else
+    if ( !test_and_set_bit(PF_CONSOLEWRITEBUG, &current->flags) )
+    {
+        printk("DOM%llu is attempting to use the deprecated "
+               "HYPERVISOR_console_write() interface.\n", current->domain);
+        printk(" - For testing, create a debug build of Xen\n");
+        printk(" - For production, your OS must use the new console model\n");
+    }
     return -ENOSYS;
 #endif
 }
index cbfec1cb1c9402ca8f37d7689d6c7aacdfcd1014..475b0924edd554c9eb969daf9b83d763bba6433c 100644 (file)
@@ -39,6 +39,7 @@ extern struct mm_struct init_mm;
 #define PF_CONSTRUCTED  3 /* Has the guest OS been fully built yet?      */
 #define PF_IDLETASK     4 /* Is this one of the per-CPU idle domains?    */
 #define PF_PRIVILEGED   5 /* Is this domain privileged?                  */
+#define PF_CONSOLEWRITEBUG 6 /* Has this domain used the obsolete console? */
 
 #include <xeno/vif.h>
 #include <xeno/vbd.h>
index 21149a0f9ea1cdc146ce33ed2ec52fc9513ed173..f0c475200dc43d3425a180bbec8bdb46f88fcb82 100644 (file)
@@ -41,12 +41,9 @@ static void nonpriv_conwrite(const char *s, unsigned int count)
     control_if_t *ctrl_if;
     evtchn_op_t   evtchn_op;
     int           src, dst, p;
-    unsigned long flags;
 
     ctrl_if = (control_if_t *)((char *)HYPERVISOR_shared_info + 2048);
 
-    spin_lock_irqsave(&xeno_console_lock, flags);
-
     while ( count != 0 )
     {
         /* Wait for the request ring to drain. */
@@ -74,8 +71,6 @@ static void nonpriv_conwrite(const char *s, unsigned int count)
         s     += src;
         count -= src;
     }
-
-    spin_unlock_irqrestore(&xeno_console_lock, flags);
 }
 
 static void priv_conwrite(const char *s, unsigned int count)
@@ -95,10 +90,13 @@ static void priv_conwrite(const char *s, unsigned int count)
 static void xen_console_write(struct console *co, const char *s, 
                               unsigned int count)
 {
+    unsigned long flags;
+    spin_lock_irqsave(&xeno_console_lock, flags);
     if ( !(start_info.flags & SIF_INITDOMAIN) )
         nonpriv_conwrite(s, count);
     else
         priv_conwrite(s, count);
+    spin_unlock_irqrestore(&xeno_console_lock, flags);
 }
 
 static kdev_t xen_console_device(struct console *c)
@@ -167,10 +165,34 @@ static void __do_console_io(void)
     evtchn_op_t      evtchn_op;
     CONTROL_RING_IDX c;
     int              i, len, work_done = 0;
+    static char      rbuf[16];
 
-    if ( (start_info.flags & SIF_INITDOMAIN) || (xeno_console_tty == NULL) )
+    if ( xeno_console_tty == NULL )
         return;
 
+    /* Special-case I/O handling for domain 0. */
+    if ( start_info.flags & SIF_INITDOMAIN )
+    {
+        /* Receive work. */
+        while ( (len = HYPERVISOR_serial_io(SERIALIO_read, 16, rbuf)) > 0 )
+            for ( i = 0; i < len; i++ )
+                tty_insert_flip_char(xeno_console_tty, rbuf[i], 0);
+        if ( xeno_console_tty->flip.count != 0 )
+            tty_flip_buffer_push(xeno_console_tty);
+
+        /* Transmit work. */
+        if ( wc != wp )
+        {
+            len = wp - wc;
+            if ( len > (WBUF_SIZE - WBUF_MASK(wc)) )
+                len = WBUF_SIZE - WBUF_MASK(wc);
+            priv_conwrite(&wbuf[WBUF_MASK(wc)], len);
+            wc += len;
+        }
+
+        return;
+    }
+
     /* Acknowledge the notification. */
     evtchn_clear_port(0);
 
@@ -235,6 +257,7 @@ static void __do_console_io(void)
     }
 }
 
+/* This is the callback entry point for domains != 0. */
 static void control_event(unsigned int port)
 {
     unsigned long flags;
@@ -243,6 +266,15 @@ static void control_event(unsigned int port)
     spin_unlock_irqrestore(&xeno_console_lock, flags);
 }
 
+/* This is the callback entry point for domain 0. */
+static void control_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+    unsigned long flags;
+    spin_lock_irqsave(&xeno_console_lock, flags);
+    __do_console_io();
+    spin_unlock_irqrestore(&xeno_console_lock, flags);    
+}
+
 static int xeno_console_write_room(struct tty_struct *tty)
 {
     return WBUF_SIZE - (wp - wc);
@@ -290,13 +322,6 @@ static void xeno_console_flush_buffer(struct tty_struct *tty)
 static inline int __xeno_console_put_char(int ch)
 {
     char _ch = (char)ch;
-
-    if ( start_info.flags & SIF_INITDOMAIN )
-    {
-        priv_conwrite(&_ch, 1);
-        return 1;
-    }
-
     if ( (wp - wc) == WBUF_SIZE )
         return 0;
     wbuf[WBUF_MASK(wp++)] = _ch;
@@ -345,7 +370,6 @@ static void xeno_console_flush_chars(struct tty_struct *tty)
 {
     unsigned long flags;
     spin_lock_irqsave(&xeno_console_lock, flags);
-
     __do_console_io();
     spin_unlock_irqrestore(&xeno_console_lock, flags);    
 }
@@ -418,8 +442,12 @@ int __init xeno_con_init(void)
     {
         if ( evtchn_request_port(0, control_event) != 0 )
             BUG();
-        /* Kickstart event delivery. */
-        control_event(0);
+        control_event(0); /* kickstart the console */
+    }
+    else
+    {
+        request_irq(_EVENT_CONSOLE, control_irq, 0, "console", NULL);
+        control_irq(0, NULL, NULL); /* kickstart the console */
     }
 
     printk("Xeno console successfully installed\n");